package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.common.ErrorCode;
import com.example.demo.context.UserContext;
import com.example.demo.entity.*;
import com.example.demo.exception.BusinessException;
import com.example.demo.mapper.*;
import com.example.demo.service.ChildService;
import com.example.demo.vo.*;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (Child)表服务实现类
 *
 * @author makejava
 * @since 2025-01-27 22:47:01
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ChildServiceImpl extends ServiceImpl<ChildMapper, Child> implements ChildService {

    private final ChildMapper childMapper;
    private final GrowthRecordMapper growthRecordMapper;
    private final VaccineRecordMapper vaccineRecordMapper;
    private final CheckupAppointmentMapper checkupMapper;
    private final HealthAlertMapper healthAlertMapper;

    @Override
    public List<Child> listAll() {
        log.info("从数据库查询数据，userId: {}", UserContext.getUserId());
        LambdaQueryWrapper<Child> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Child::getUserId, UserContext.getUserId());
        List<Child> result = list(lambdaQueryWrapper);
        log.info("查询结果: {}", result);
        return result;
    }

    @Override
    public ChildProfileVO getChildProfile(Long childId) {
        ChildProfileVO profileVO = new ChildProfileVO();

        try {
            // 1. 获取儿童基本信息
            Child child = childMapper.selectById(childId);
            if (child == null) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }

            // 2. 复制基本信息
            BeanUtils.copyProperties(child, profileVO);
            profileVO.setAge(calculateAge(child.getBirthday()));

            // 3. 获取生长记录
            List<GrowthRecord> growthRecords = growthRecordMapper.selectList(
                    new LambdaQueryWrapper<GrowthRecord>()
                            .eq(GrowthRecord::getChildId, childId)
                            .orderByDesc(GrowthRecord::getRecordTime)
            );
            List<GrowthRecordVO> growthVOs = growthRecords.stream()
                    .map(this::convertToGrowthVO)
                    .collect(Collectors.toList());
            profileVO.setGrowthRecords(growthVOs);

            // 4. 获取疫苗接种记录
            List<VaccineRecord> vaccineRecords = vaccineRecordMapper.selectList(
                    new LambdaQueryWrapper<VaccineRecord>()
                            .eq(VaccineRecord::getChildId, childId)
                            .orderByDesc(VaccineRecord::getVaccineDate)
            );
            List<VaccineRecordVO> vaccineVOs = vaccineRecords.stream()
                    .map(this::convertToVaccineVO)
                    .collect(Collectors.toList());
            profileVO.setVaccineRecords(vaccineVOs);

            // 5. 获取体检记录
            List<CheckupAppointment> checkups = checkupMapper.selectList(
                    new LambdaQueryWrapper<CheckupAppointment>()
                            .eq(CheckupAppointment::getChildId, childId)
                            .orderByDesc(CheckupAppointment::getAppointmentTime)
            );
            List<CheckupVO> checkupVOs = checkups.stream()
                    .map(this::convertToCheckupVO)
                    .collect(Collectors.toList());
            profileVO.setCheckupRecords(checkupVOs);

            // 6. 获取健康提醒
            List<HealthAlert> alerts = healthAlertMapper.selectList(
                    new LambdaQueryWrapper<HealthAlert>()
                            .eq(HealthAlert::getChildId, childId)
                            .eq(HealthAlert::getStatus, 0)  // 未处理的提醒
                            .orderByDesc(HealthAlert::getAlertTime)
            );
            List<HealthAlertVO> alertVOs = alerts.stream()
                    .map(this::convertToAlertVO)
                    .collect(Collectors.toList());
            profileVO.setHealthAlerts(alertVOs);

            return profileVO;

        } catch (BusinessException e) {
            log.error("获取儿童档案信息失败，childId: {}, 错误信息: {}", childId, e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("获取儿童档案信息异常，childId: {}", childId, e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
    }

    // 转换方法
    private GrowthRecordVO convertToGrowthVO(GrowthRecord record) {
        if (record == null) return null;
        GrowthRecordVO vo = new GrowthRecordVO();
        vo.setId(record.getId());
        vo.setDate(record.getRecordTime());
        vo.setHeight(record.getHeight());
        vo.setWeight(record.getWeight());
        vo.setBmi(record.getBmi());
        return vo;
    }

    private VaccineRecordVO convertToVaccineVO(VaccineRecord record) {
        if (record == null) return null;
        VaccineRecordVO vo = new VaccineRecordVO();
        vo.setId(record.getId());
        vo.setVaccineName(record.getVaccineName());
        vo.setVaccineDate(record.getVaccineDate());
        vo.setNextDate(record.getNextDate());
        vo.setStatus(record.getStatus());
        return vo;
    }

    private CheckupVO convertToCheckupVO(CheckupAppointment checkup) {
        if (checkup == null) return null;
        CheckupVO vo = new CheckupVO();
        vo.setId(checkup.getId());
        vo.setAppointmentTime(checkup.getAppointmentTime());
        vo.setCheckupType(checkup.getCheckupType());
        vo.setStatus(checkup.getStatus());
        return vo;
    }

    private HealthAlertVO convertToAlertVO(HealthAlert alert) {
        if (alert == null) return null;
        HealthAlertVO vo = new HealthAlertVO();
        vo.setId(alert.getId());
        vo.setType(alert.getType());
        vo.setMessage(alert.getMessage());
        vo.setAlertTime(alert.getAlertTime());
        vo.setStatus(alert.getStatus());
        return vo;
    }

    // 计算年龄
    private Integer calculateAge(Date birthday) {
        if (birthday == null) {
            return null;
        }
        LocalDate birthDate = birthday.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDate();
        return Period.between(birthDate, LocalDate.now()).getYears();
    }

    @Override
    public List<Child> getChildrenByUserId(Long userId) {
        LambdaQueryWrapper<Child> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Child::getUserId, userId);
        return list(lambdaQueryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addChild(Child child) {
        child.setCreateTime(new Date());
        child.setUpdateTime(new Date());
        return save(child);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateChild(Child child) {
        child.setUpdateTime(new Date());
        return updateById(child);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteChild(Long id) {
        return removeById(id);
    }

    @Override
    public Child getChildById(Long id) {
        return getById(id);
    }
}
